package com.cloudwave.trailends.service;

import java.util.ArrayList;
import java.util.List;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.database.Cursor;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.cloudwave.trailends.AppContext;
import com.cloudwave.trailends.Constants;
import com.cloudwave.trailends.R;
import com.cloudwave.trailends.domain.LinePoint;
import com.cloudwave.trailends.domain.RidingLine;
import com.cloudwave.trailends.domain.User;
import com.cloudwave.trailends.entity.ResultEntity;
import com.cloudwave.trailends.entity.SyncDataEntity;
import com.cloudwave.trailends.entity.SyncIdEntity;
import com.cloudwave.trailends.ui.HistoryActivity;
import com.cloudwave.trailends.utils.CollectionUtils;
import com.cloudwave.trailends.utils.StatisticsUtils;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.db.sqlite.WhereBuilder;
import com.lidroid.xutils.db.table.DbModel;
import com.lidroid.xutils.exception.DbException;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;

public class SyncService extends Service {
	private static final String TAG = "SyncService";
	public static final int NOTIF_SYNC = 101;
	
	public static final String SYNC_SERVICE = "com.cloudwave.trailends.SyncService";
	
	public static final String SYNC_OVER = "sync_over";
	public static final String SYNC_REFRESH = "sync_refresh";
	public static final String SYNC_ING = "sync_ing";
	
	public static boolean isSyncing = false;
	
	private NotificationManager notificationManager; 
	private Notification notification;
	private NotificationCompat.Builder builder;
	
	private DbUtils dbu = null;
	private HttpUtils http = null;
	
	private int dataCount = 0;
	
	
	@Override
	public IBinder onBind(Intent intent) {
		Log.i(TAG, "onBind!");
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		Log.i(TAG, "onCreate!");
		
		//自定义通知栏视图
		RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notice_sync_service_simple);
		contentView.setTextViewText(R.id.tvSyncNoticeTitle, "数据同步");
		contentView.setTextViewText(R.id.tvSyncNoticeStatus, "开始同步数据...");
		
		//定义点击通知小时时的动作
		Intent resuliIntent = new Intent(SyncService.this, HistoryActivity.class);
		resuliIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //销毁当前栈中的其他所有activity
		PendingIntent resultPendingIntent = PendingIntent.getActivity(SyncService.this, 0, resuliIntent, PendingIntent.FLAG_CANCEL_CURRENT);
		
		//设置通知消息属性
		builder = new NotificationCompat.Builder(SyncService.this)
			.setOngoing(true)
			.setSmallIcon(R.drawable.notice_ico)
			.setContentTitle("数据同步")
			.setContent(contentView)
			.setContentIntent(resultPendingIntent)
			.setTicker("数据同步开始...");
		
		//创建通知消息
		notification = builder.build();
		
		notificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
//		notificationManager.notify(NOTIF_RIDING, notification);
		
		// 把当前服务设定为前台服务，并指定显示的通知。
		startForeground(NOTIF_SYNC, notification);
		
		initDb();
		
		initHttp();
		
		findDeleteData();
	}
	
	
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(TAG, "onStartCommand!");
		if ( !isSyncing ) {
			findDeleteData();
		}
		return super.onStartCommand(intent, flags, startId);
	}

	private void initDb() {
		if ( dbu == null ) {
			dbu = DbUtils.create(this.getApplicationContext(), Constants.DB_NAME);
		}
	}
	
	private void initHttp() {
		if ( http == null ) {
			http = new HttpUtils();
		}
	}
	
	private void findDeleteData() {
		isSyncing = true;
		Log.i(TAG, "findDeleteData!");
		notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "查询要删除的骑记...");
		notificationManager.notify(NOTIF_SYNC, notification);
		
		try {
			String sql = "select remoteId_ from te_ridingline where crudStatus_ = 3 and remoteId_ is not null";
			Cursor cursor = dbu.execQuery(sql);
			if ( cursor != null && cursor.getCount() > 0 ) {
				List<Long> remoteIdList = new ArrayList<Long>();
				while (cursor.moveToNext()) {  
				    long remoteId = cursor.getLong(cursor.getColumnIndex("remoteId_"));
				    remoteIdList.add(remoteId);
				}
				dealDeteteData(Constants.URL_SYNC_DELETE, remoteIdList);
			} else {
				notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "没有要删除的骑记...");
				notificationManager.notify(NOTIF_SYNC, notification);
				
				countRemoteData();
			}
		} catch (DbException e) {
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "加载要删除的骑记失败...");
			notificationManager.notify(NOTIF_SYNC, notification);
			
			//加载删除数据失败则继续
			countRemoteData();
			Log.e(TAG, "加载要删除的骑记失败", e);
		}
	}
	
	private void dealDeteteData(String url, List<Long> remoteIdList) {
		Log.i(TAG, "dealDeteteData!");
		RequestParams params = new RequestParams();
		StatisticsUtils.newInstance(this).appendParams("1", params);
		params.addBodyParameter("token", ((AppContext) getApplication()).getToken());
		params.addBodyParameter("data", JSON.toJSONString(remoteIdList));
		
		http.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
			@Override
			public void onSuccess(ResponseInfo<String> responseInfo) {
				
				if (responseInfo.statusCode != 200 && TextUtils.isEmpty(responseInfo.result)) {
					Toast.makeText(SyncService.this, "未获取到返回数据,请重试!", Toast.LENGTH_SHORT).show();
					notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "未获取到返回数据,请重试!");
					notificationManager.notify(NOTIF_SYNC, notification);
					Intent intent = new Intent();
		 			intent.setAction(SYNC_OVER);
		 			sendBroadcast(intent);
					isSyncing = false;
					
					return ;
				} else {
					ResultEntity rt = JSON.parseObject(responseInfo.result, ResultEntity.class);
					Log.v(TAG, "获取到返回数据:"+JSON.toJSONString(rt));
					if ( rt.isSuccess() && rt.hasData() ) {
						
						afterDeleteData(rt.data);
						
					} else {
						Toast.makeText(SyncService.this, rt.getCodeMsg(), Toast.LENGTH_SHORT).show();
						notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, rt.getCodeMsg());
						notificationManager.notify(NOTIF_SYNC, notification);
						Intent intent = new Intent();
			 			intent.setAction(SYNC_OVER);
			 			sendBroadcast(intent);
						isSyncing = false;
					}
				}
			}
			
			@Override
			public void onFailure(HttpException error, String msg) {
				Toast.makeText(SyncService.this, "删除远程数据失败，请检查您的网络!", Toast.LENGTH_SHORT).show();
				notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "删除远程数据失败，请检查您的网络!");
				notificationManager.notify(NOTIF_SYNC, notification);
				Intent intent = new Intent();
	 			intent.setAction(SYNC_OVER);
	 			sendBroadcast(intent);
				isSyncing = false;
				Log.e(TAG, "删除远程数据失败", error);
			}
		});
	}
	
	private void afterDeleteData(Object data) {
		Log.i(TAG, "afterDeleteData!");
		try {
			List<Long> rlList = JSON.parseArray(data.toString(), Long.class);
//				dbu.delete(entity) ##考虑使用这种API
			String idStr = rlList.toString().replace("[", "").replace("]", "");
			String sql = "delete from te_ridingline where remoteId_ in ("+idStr+")";
			Log.v(TAG, "delete sql:"+sql);
			dbu.execNonQuery(sql);
			
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "删除本地数据完成...");
			notificationManager.notify(NOTIF_SYNC, notification);
		} catch (DbException e) {
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "删除本地数据异常...");
			notificationManager.notify(NOTIF_SYNC, notification);
			Intent intent = new Intent();
 			intent.setAction(SYNC_OVER);
 			sendBroadcast(intent);
			isSyncing = false;
			Log.e(TAG, "删除本地数据异常", e);
		}
		
		countRemoteData();
	}
	
	private void countRemoteData() {
		isSyncing = true;
		Log.i(TAG, "countRemoteData!");
		notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "统计本地数据...");
		notificationManager.notify(NOTIF_SYNC, notification);
		
		try {
			RidingLine rl = dbu.findFirst(Selector.from(RidingLine.class).where("remoteId_", "!=", null)
					.orderBy("timestamp_", true));
			if ( rl != null ) {
				LinePoint lp = dbu.findFirst(Selector.from(LinePoint.class).where("remoteId_", "!=", null)
						.where("ridingline_id", "=", rl.getId()).orderBy("timestamp_", true));
				dealCountRemoteData(Constants.URL_SYNC_DOWNLOAD_COUNT, rl.getRemoteId(), lp.getTimestamp());
			} else {
				dealCountRemoteData(Constants.URL_SYNC_DOWNLOAD_COUNT, null, null);
			}
		} catch (DbException e) {
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "统计本地数据异常...");
			notificationManager.notify(NOTIF_SYNC, notification);
			Intent intent = new Intent();
 			intent.setAction(SYNC_OVER);
 			sendBroadcast(intent);
			isSyncing = false;
			Log.e(TAG, "统计本地数据异常", e);
		}
	}
	
	private void dealCountRemoteData(String url, Long rlId, Long timestamp) {
		Log.i(TAG, "dealCountRemoteData!");
		RequestParams params = new RequestParams();
		StatisticsUtils.newInstance(this).appendParams("1", params);
		params.addBodyParameter("token", ((AppContext) getApplication()).getToken());
		
		if ( rlId != null ) {
			params.addBodyParameter("rlId", String.valueOf(rlId));
		}
		if ( timestamp != null ) {
			params.addBodyParameter("lastTimestamp", String.valueOf(timestamp));
		}
		
		http.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
			@Override
			public void onSuccess(ResponseInfo<String> responseInfo) {
				
				if (responseInfo.statusCode != 200 && TextUtils.isEmpty(responseInfo.result)) {
					Toast.makeText(SyncService.this, "未获取到远程数据!", Toast.LENGTH_SHORT).show();
					notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "未获取到远程数据...");
					notificationManager.notify(NOTIF_SYNC, notification);
					Intent intent = new Intent();
		 			intent.setAction(SYNC_OVER);
		 			sendBroadcast(intent);
					isSyncing = false;
					return ;
				} else {
					ResultEntity rt = JSON.parseObject(responseInfo.result, ResultEntity.class);
					if ( rt.isSuccess() && rt.hasData() ) {
						
						afterCountRemoteData(rt.data);
						
					} else {
						Toast.makeText(SyncService.this, rt.getCodeMsg(), Toast.LENGTH_SHORT).show();
						notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, rt.getCodeMsg());
						notificationManager.notify(NOTIF_SYNC, notification);
						Intent intent = new Intent();
			 			intent.setAction(SYNC_OVER);
			 			sendBroadcast(intent);
						isSyncing = false;
						return ;
					}
				}
			}
			
			@Override
			public void onFailure(HttpException error, String msg) {
				Toast.makeText(SyncService.this, "统计远程数据失败，请检查您的网络!", Toast.LENGTH_SHORT).show();
				notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "统计远程数据失败，请检查您的网络!");
				notificationManager.notify(NOTIF_SYNC, notification);
				Intent intent = new Intent();
	 			intent.setAction(SYNC_OVER);
	 			sendBroadcast(intent);
				isSyncing = false;
				Log.e(TAG, "统计远程数据失败", error);
			}
		});
	}
	
	private void afterCountRemoteData(Object data) {
		Log.i(TAG, "afterCountRemoteData!");
		dataCount = (int) Long.parseLong(data.toString());
		
		if ( dataCount == 0 ) {
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "没有要下载的数据...");
			notificationManager.notify(NOTIF_SYNC, notification);
			
			findUploadData(true);
			
		} else {
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "查询到远程数据("+dataCount+")...");
			notificationManager.notify(NOTIF_SYNC, notification);
			
			findDownloadData(null);
		}
	}
	
	// 处理下载
	private void findDownloadData(Long rlId) {
		isSyncing = true;
		Log.i(TAG, "findDownloadData!");
		
		try {
			RidingLine rl = null;
			if ( rlId == null ) {
				rl = dbu.findFirst(Selector.from(RidingLine.class).where("remoteId_", "!=", null)
					.orderBy("timestamp_", true));
			} else {
				rl = dbu.findById(RidingLine.class, rlId);
			}
			
			if ( rl != null ) {
				LinePoint lp = dbu.findFirst(Selector.from(LinePoint.class).where("remoteId_", "!=", null)
						.and("ridingline_id", "=", rl.getId()).orderBy("timestamp_", true));
				if ( lp != null ) {
					dealDownloadData(Constants.URL_SYNC_DOWNLOAD, rl.getRemoteId(), lp.getTimestamp());
				} else {
					dealDownloadData(Constants.URL_SYNC_DOWNLOAD, rl.getRemoteId(), null);
				}
			} else {
				dealDownloadData(Constants.URL_SYNC_DOWNLOAD, null, null);
			}
			
			Intent intent = new Intent();
 			intent.setAction(SYNC_ING);
 			sendBroadcast(intent);
		} catch (DbException e) {
			Toast.makeText(SyncService.this, "查询下载数据异常!", Toast.LENGTH_SHORT).show();
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "查询下载数据异常...");
			notificationManager.notify(NOTIF_SYNC, notification);
			Intent intent = new Intent();
 			intent.setAction(SYNC_OVER);
 			sendBroadcast(intent);
			isSyncing = false;
			Log.e(TAG, "查询下载数据异常", e);
		}
	}
		
	private void dealDownloadData(String url, Long rlId, Long timestamp) {
		Log.i(TAG, "dealDownloadData!");
		RequestParams params = new RequestParams();
		StatisticsUtils.newInstance(this).appendParams("1", params);
		params.addBodyParameter("token", ((AppContext) getApplication()).getToken());
		if ( rlId != null ) {
			params.addBodyParameter("rlId", String.valueOf(rlId));
		}
		if ( timestamp != null ) {
			params.addBodyParameter("lastTimestamp", String.valueOf(timestamp));
		}
		
		http.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
			@Override
			public void onSuccess(ResponseInfo<String> responseInfo) {
				
				if ( responseInfo.statusCode != 200 && TextUtils.isEmpty(responseInfo.result) ) {
					Toast.makeText(SyncService.this, "未获取到远程数据,请重试!", Toast.LENGTH_SHORT).show();
					notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "未获取到远程数据...");
					notificationManager.notify(NOTIF_SYNC, notification);
					Intent intent = new Intent();
		 			intent.setAction(SYNC_OVER);
		 			sendBroadcast(intent);
					isSyncing = false;
				} else {
					ResultEntity rt = JSON.parseObject(responseInfo.result, ResultEntity.class);
					Log.v(TAG, "获取到返回数据:"+JSON.toJSONString(rt));
					if ( rt.isSuccess() && rt.hasData() ) {
						Log.i(TAG, "结果数据:"+responseInfo.result);
						
						afterDownloadData(rt.data);
						
					} else {
						Toast.makeText(SyncService.this, rt.getCodeMsg(), Toast.LENGTH_SHORT).show();
						notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, rt.getCodeMsg());
						notificationManager.notify(NOTIF_SYNC, notification);
						Intent intent = new Intent();
			 			intent.setAction(SYNC_OVER);
			 			sendBroadcast(intent);
						isSyncing = false;
					}
				}
			}
			
			@Override
			public void onFailure(HttpException error, String msg) {
				Toast.makeText(SyncService.this, "请求下载数据失败，请检查您的网络!", Toast.LENGTH_SHORT).show();
				notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "请求下载数据失败，请检查您的网络!");
				notificationManager.notify(NOTIF_SYNC, notification);
				Intent intent = new Intent();
	 			intent.setAction(SYNC_OVER);
	 			sendBroadcast(intent);
				isSyncing = false;
				Log.e(TAG, "请求下载数据失败", error);
			}
		});
	}
	
	private void afterDownloadData(Object data) {
		Log.i(TAG, "afterDownloadData!");
		SyncDataEntity downloadEntity = JSON.parseObject(data.toString(), SyncDataEntity.class);
		
		int curSize = dataCount - (int) downloadEntity.getTotalSize();
		
		String numStr = this.getResources().getString(R.string.notice_num);
		String numNewStr = String.format(numStr, curSize, dataCount);
		
		if ( downloadEntity.getTotalSize() == 0 ) {
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "数据下载完成...");
			notificationManager.notify(NOTIF_SYNC, notification);
			
			Intent intent = new Intent();
 			intent.setAction(SYNC_REFRESH);
 			sendBroadcast(intent);
 			
 			findUploadData(true);
		} else {
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "数据下载中("+numNewStr+")...");
			notificationManager.notify(NOTIF_SYNC, notification);
			
			RidingLine entity = downloadEntity.getEntity();
			
			try {
				long count = dbu.count(Selector.from(RidingLine.class).where("remoteId_", "=", entity.getRemoteId()));
				if ( count == 0 ) {
//					entity.setRemoteId(entity.getId());  //服务端已经处理了
//					entity.setId(null);
					entity.setSendStatus(1);
					entity.setCrudStatus(0);
					entity.setCreator(((AppContext) getApplication()).loadLoginUser());
					
					dbu.saveBindingId(entity);
				} else {
					entity = dbu.findFirst(Selector.from(RidingLine.class).where("remoteId_", "=", entity.getRemoteId()));
				}
				
				List<LinePoint> lpList = downloadEntity.getSubEntityList();
				
				if ( CollectionUtils.isNotEmpty(lpList) ) {
					for ( LinePoint lp : lpList ) {
						lp.setRemoteId(lp.getId());
						lp.setId(null);
						lp.setRidingLine(entity);
						lp.setSendStatus(1);
						lp.setCrudStatus(0);
						lp.setCreatorId(((AppContext) getApplication()).getUid());
						
						dbu.save(lp);
					}
					
					if ( lpList.size() < downloadEntity.getPageSize() ) {  //如果实际数量小于每页的数量，说明当前正在同步的骑记已经同步完了
						Intent intent = new Intent();
			 			intent.setAction(SYNC_REFRESH);
			 			sendBroadcast(intent);
			 			
			 			findDownloadData(entity.getId());
					} else {
						if ( downloadEntity.getTotalSize() <= downloadEntity.getPageSize() ) {  //如果剩余数量没有每页数量大说明没有了
							findUploadData(true);
						} else {
							findDownloadData(entity.getId());
						}
					}
				} else {
					findDownloadData(entity.getId());
				}
			} catch (DbException e) {
				Toast.makeText(SyncService.this, "写入下载数据异常~_~", Toast.LENGTH_SHORT).show();
				notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "写入下载数据异常...");
				notificationManager.notify(NOTIF_SYNC, notification);
				
				Intent intent = new Intent();
	 			intent.setAction(SYNC_OVER);
	 			sendBroadcast(intent);
				isSyncing = false;
				Log.e(TAG, "写入下载数据异常", e);
			}
		}
	}
	
	
	//处理上传
	private void findUploadData(boolean isFirstUpload) {
		isSyncing = true;
		Log.i(TAG, "findUploadData!");
		try {
			List<RidingLine> rlList = dbu.findAll(Selector.from(RidingLine.class).where("remoteId_", "=", null).and("isNow_", "=", "1"));
			
			//未上传，不是当前骑记并且已经结束的数据
			//这里导致没有坐标点的骑记无法上传###
			Selector selector = Selector.from(LinePoint.class).where("remoteId_", "=", null).and("ridingline_id", "!=", null);
			if ( CollectionUtils.isNotEmpty(rlList) ) {
				for ( RidingLine rlNow : rlList ) {
					selector.and("ridingline_id", "!=", rlNow.getId());
				}
			}
			
			long count = dbu.count(selector);
			
			if ( count == 0 ) {
				Toast.makeText(SyncService.this, "数据同步完成^_^", Toast.LENGTH_SHORT).show();
				notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "数据同步完成.");
				notificationManager.notify(NOTIF_SYNC, notification);
				
				Intent intent = new Intent();
	 			intent.setAction(SYNC_OVER);
	 			sendBroadcast(intent);
	 			statUserData();
	 			if ( dbu != null ) {
	 				dbu.close();
	 				dbu = null;
	 			}
	 			
	 			SyncService.isSyncing = false;
	 			stopForeground(true);
				SyncService.this.stopSelf();
				
			} else {
				
				Intent intent = new Intent();
	 			intent.setAction(SYNC_ING);
	 			sendBroadcast(intent);
	 			
				if ( isFirstUpload ) {
					dataCount = (int) count;
					String numStr = this.getResources().getString(R.string.notice_num);
					String numNewStr = String.format(numStr, 0, dataCount); 
					
					notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "数据上传中("+numNewStr+")...");
					notificationManager.notify(NOTIF_SYNC, notification);
				} else {
					String numStr = this.getResources().getString(R.string.notice_num);
					String numNewStr = String.format(numStr, (dataCount - count), dataCount); 
					
					notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "数据上传中("+numNewStr+")...");
					notificationManager.notify(NOTIF_SYNC, notification);
				}
				
//				List<RidingLine> dList = dbu.findAll(RidingLine.class);
//				StringBuffer ids = new StringBuffer();
//				for ( RidingLine d : dList ) {
//					ids.append(d.getId()).append(",");
//				}
//				ids.deleteCharAt(ids.length()-1);
//				String sql = "delete from te_linepoint where ridingline_id not in("+ids.toString()+")";
//				dbu.execNonQuery(sql);
				
				
				LinePoint lp = dbu.findFirst(Selector.from(LinePoint.class).where("remoteId_", "=", null).and("ridingline_id", "!=", null).orderBy("timestamp_", false));
				lp.getRidingLine().setLpLoader(null);
				SyncDataEntity uploadEntity = new SyncDataEntity();
				lp.getRidingLine().setCreator(null);
				if ( lp.getRidingLine().getRemoteId() != null ) {
					RidingLine rlTmp = new RidingLine();
					rlTmp.setId(lp.getRidingLine().getId());
					rlTmp.setRemoteId(lp.getRidingLine().getRemoteId());
					uploadEntity.setEntity(rlTmp);
					
					List<LinePoint> lpList = dbu.findAll(Selector.from(LinePoint.class).where("ridingline_id", "=", lp.getRidingLine().getId()).and("remoteId_", "=", null).orderBy("timestamp_", false).limit(5));
					if ( CollectionUtils.isNotEmpty(lpList) ) {
						for ( LinePoint lpTmp : lpList ) {
							lpTmp.setRidingLine(null);
							lpTmp.setCreator(null);
						}
						uploadEntity.setSubEntityList(lpList);
					} else {
						uploadEntity.setSubEntityList(new ArrayList<LinePoint>());
					}
					
				} else {
					uploadEntity.setEntity(lp.getRidingLine());
					uploadEntity.setSubEntityList(new ArrayList<LinePoint>());
				}
				
				uploadEntity.setPageSize(5);
				dealUploadData(Constants.URL_SYNC_UPLOAD, uploadEntity);
			}
		} catch (DbException e) {
			Toast.makeText(SyncService.this, "查询上传数据异常~_~", Toast.LENGTH_SHORT).show();
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "查询上传数据异常...");
			notificationManager.notify(NOTIF_SYNC, notification);
			
			statUserData();
			Intent intent = new Intent();
 			intent.setAction(SYNC_OVER);
 			sendBroadcast(intent);
			isSyncing = false;
			Log.e(TAG, "查询上传数据异常", e);
		}
	}
	
	private void dealUploadData(String url, SyncDataEntity uploadEntity) {
		Log.i(TAG, "dealUploadData!");
		RequestParams params = new RequestParams();
		StatisticsUtils.newInstance(this).appendParams("1", params);
		params.addBodyParameter("token", ((AppContext) getApplication()).getToken());
		params.addBodyParameter("data", JSON.toJSONString(uploadEntity));
		
		http.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
			@Override
			public void onSuccess(ResponseInfo<String> responseInfo) {
				
				if (responseInfo.statusCode != 200 && TextUtils.isEmpty(responseInfo.result)) {
					Toast.makeText(SyncService.this, "未获取到返回数据,请重试!", Toast.LENGTH_SHORT).show();
					notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "未获取到返回数据,请重试!");
					notificationManager.notify(NOTIF_SYNC, notification);
				} else {
					ResultEntity rt = JSON.parseObject(responseInfo.result, ResultEntity.class);
					Log.v(TAG, "获取到返回数据:"+JSON.toJSONString(rt));
					if ( rt.isSuccess() && rt.hasData() ) {
						
						afterUploadData(rt.data);
						
					} else {
						Toast.makeText(SyncService.this, rt.getCodeMsg(), Toast.LENGTH_SHORT).show();
						notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, rt.getCodeMsg());
						notificationManager.notify(NOTIF_SYNC, notification);
						statUserData();
						Intent intent = new Intent();
			 			intent.setAction(SYNC_OVER);
			 			sendBroadcast(intent);
						isSyncing = false;
						return ;
					}
				}
			}
			
			@Override
			public void onFailure(HttpException error, String msg) {
				Toast.makeText(SyncService.this, "上传数据失败，请检查您的网络!", Toast.LENGTH_SHORT).show();
				notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "上传数据失败，请检查您的网络!");
				notificationManager.notify(NOTIF_SYNC, notification);
				
				statUserData();
				Intent intent = new Intent();
	 			intent.setAction(SYNC_OVER);
	 			sendBroadcast(intent);
				isSyncing = false;
				Log.e(TAG, "上传数据失败", error);
			}
		});
	}
	
	private void afterUploadData(Object data) {
		Log.i(TAG, "afterUploadData!");
		SyncIdEntity idEntity = JSON.parseObject(data.toString(), SyncIdEntity.class);
		
		try {
			RidingLine rl = dbu.findFirst(Selector.from(RidingLine.class).where("id_", "=", idEntity.id));
			rl.setRemoteId(idEntity.remoteId);
			rl.setSendStatus(1);
			rl.setCrudStatus(0);
			dbu.update(rl, WhereBuilder.b("id_", "=", rl.getId()), "remoteId_", "sendStatus_", "crudStatus_");
			
			if ( CollectionUtils.isNotEmpty(idEntity.idList) ) {
				for ( SyncIdEntity subIdEntity : idEntity.idList ) {
					LinePoint lp = dbu.findFirst(Selector.from(LinePoint.class).where("id_", "=", subIdEntity.id));
					lp.setRemoteId(subIdEntity.remoteId);
					lp.setSendStatus(1);
					lp.setCrudStatus(0);
					dbu.update(lp, WhereBuilder.b("id_", "=", subIdEntity.id), "remoteId_", "sendStatus_", "crudStatus_");
				}
			}
			
			findUploadData(false);
			
		} catch (DbException e) {
			Toast.makeText(SyncService.this, "更新上传数据异常~_~", Toast.LENGTH_SHORT).show();
			notification.contentView.setTextViewText(R.id.tvSyncNoticeStatus, "更新上传数据异常~_~");
			notificationManager.notify(NOTIF_SYNC, notification);
			
			Intent intent = new Intent();
 			intent.setAction(SYNC_OVER);
 			sendBroadcast(intent);
 			statUserData();
			isSyncing = false;
			Log.e(TAG, "更新上传数据异常", e);
		}
		
	}
	
	private boolean statUserData() {
		User user = ((AppContext) getApplication()).loadLoginUser();
		if ( user != null ) {
			try {
				long count = dbu.count(Selector.from(RidingLine.class).where("crudStatus_", "!=", 3));
				if ( count == 0 ) {
					user.setTotalRidingLine(0);
					user.setTotalMileage(0);
					user.setTotalLinePoint(0);
					user.setTotalRidingTime(0);
				} else {
					DbModel dbModel = dbu.findDbModelFirst(Selector.from(RidingLine.class).select("COUNT(id_) AS num,SUM(totalMileage_) AS totalMileage,SUM(totalPoint_) AS totalPoint,SUM(totalTime_) AS totalTime").where("isNow_", "==", 0));
					if (dbModel != null && !dbModel.getDataMap().isEmpty()) {
						int num = dbModel.getInt("num");
						float totalMileage = dbModel.getFloat("totalMileage");
						int totalPoint = dbModel.getInt("totalPoint");
						long totalTime = dbModel.getInt("totalTime");
						
						user.setTotalRidingLine(num);
						user.setTotalMileage(totalMileage);
						user.setTotalLinePoint(totalPoint);
						user.setTotalRidingTime(totalTime);
					}
				}
				
				((AppContext) getApplication()).updateLoginUser(user);
				return true;
				
			} catch (DbException e) {
				Log.e(TAG, "统计个人数据异常", e);
				return false;
			}
		}
		return true;
	}
}
